import Taro from '@tarojs/taro'
import React, { PureComponent } from 'react';
import { Block, Text, View, ScrollView, Image } from '@tarojs/components'
import { getWindowHeight } from '@/utils/style'
import classNames from 'classnames'
import uniq from 'lodash/uniq'
import uniqBy from 'lodash/uniqBy'
import differenceBy from 'lodash/differenceBy'
import xor from 'lodash/xor'
import xorBy from 'lodash/xorBy'
import Menu from './menu'
import Content from './content'
import EditMenuList from './edit-menu-list'
import { item, subItem, categoryType } from './index.d'
import './index.scss'
import Border1PxLine from '@/components/border-1px-line'

type State = {
  readonly currentItems: subItem[]
  readonly currentMenu: string
  readonly currentSubList: subItem[]
  readonly highLightMenus: string[]
  readonly currentCount: number
  readonly currentHeight: number
  readonly height: string
  readonly hasRegion: boolean
}

type Props = {
  edit: boolean
  max: number
  type: categoryType
  options: item[]
  radio: boolean
  location: subItem | null
  defaultValue: subItem[]
  onItemClick?: (item: subItem) => void
  onMenuClick?: (item: subItem) => void
  onSave?: (items: subItem[]) => void
  onChange?: (items: subItem[]) => void
}

export default class Category extends PureComponent<Props, State> {
  static defaultProps = {
    edit: false,
    max: 3,
    radio: false,
    type: 'Normal',
    defaultValue: [],
    options: [],
    location: null,
  }

  readonly state: State = {
    currentItems: [],
    currentMenu: '',
    currentSubList: [],
    highLightMenus: [],
    currentCount: 0,
    currentHeight: 0,
    height: '',
    hasRegion: false
  }

  editNode: any

  componentWillMount() {
    const { edit, max, defaultValue, options, type } = this.props
    const highLightMenus: string[] = []
    if (options.length > 0) {
      let currentValues: subItem[] = []
      if (defaultValue.length > 0) {
        if (type === 'Grid') {
          currentValues = defaultValue
        } else {
          currentValues = edit && max ? defaultValue.slice(0, max) : defaultValue
          this.props.options.forEach(x => {
            currentValues.forEach(y => {
              const res = x.sublist.filter(x => x.code === y.code)
              if (res.length > 0) {
                highLightMenus.push(x.code)
              }
            })
          })
        }
      }
      let currentMenu = options[0].code
      let currentSubList = options[0].sublist
      const highLightMenusUniq = uniq(highLightMenus)
      if (highLightMenusUniq.length > 0) {
        const result = options.filter(x => x.code === highLightMenusUniq[0])[0]
        currentMenu = result.code
        currentSubList = result.sublist
      }
      this.setState(
        {
          currentItems: currentValues,
          currentMenu: currentMenu,
          currentSubList: currentSubList,
          highLightMenus: highLightMenusUniq,
          currentCount: currentValues.length,
          currentHeight: edit ? -106 - 1 : 0 - 1,
        },
        () => {
          const { currentHeight } = this.state
          let height_N =
            parseInt(getWindowHeight(false, '').toString(), 10) +
            parseInt(currentHeight.toString(), 10)
          if (edit && max > 1) {
            height_N =
              parseInt(getWindowHeight(false, '').toString(), 10) +
              parseInt(currentHeight.toString(), 10) +
              -50
          }
          const height_N2 = height_N + 'px'
          this.setState({
            height: height_N2,
          })
        }
      )
      if (defaultValue.length > 0 && type === 'List') {
        this.setState({
          currentMenu: defaultValue[0].code,
        })
      }
    } else {
      console.error('options 不能为空！')
    }
  }

  componentDidUpdate() {
    if (this.props.edit && this.editNode && this.editNode._selector) {
      const query = Taro.createSelectorQuery().in(this.$scope)
      query
        .select(this.editNode && this.editNode._selector)
        .boundingClientRect()
        .exec(res => {
          if (this.state.currentHeight != -res[0].height) {
            this.setState({ currentHeight: -res[0].height - 1 })
          }
        })
    }
    const { currentHeight, height } = this.state
    const { edit, type, options, location, max } = this.props

    let height_N =
      parseInt(getWindowHeight(false, '').toString(), 10) + parseInt(currentHeight.toString(), 10)
    if (edit && max > 1) {
      height_N =
        parseInt(getWindowHeight(false, '').toString(), 10) +
        parseInt(currentHeight.toString(), 10) +
        -50
    }
    const height_N2 = height_N + 'px'

    if (height !== height_N2) {
      this.setState({
        height: height_N2,
      })
    }
  }

  refEdit = node => {
    this.editNode = node
  }

  // 点击菜单
  handleMenuClick = (item: subItem) => {
    const { options } = this.props
    const regionCodes = ["010000", "020000", "030000", "040000"]
    const hasRegion = regionCodes.some((itemCode:string) => itemCode === item.code)

    if(hasRegion) {
      this.setState({
        hasRegion: true,
      })
    } else {
      this.setState({
        hasRegion: false,
      })
    }
    this.setState({
      currentMenu: item.code,
      currentSubList: options.filter(x => x.code === item.code)[0].sublist,
    })
    if (this.props.onMenuClick) {
      this.props.onMenuClick(item)
    }
  }

  replaceArr = (selected: any[], code: string) => {
    let selectedCode:string[] = []
    selected.forEach((item:any) => {
      selectedCode.push(item.code)
    })
    const str = code.substr(0,2)
    if(code.indexOf('0000') !== -1) {
      selectedCode = selectedCode.filter((item:any) => {
        if(item.indexOf('0000') !== -1) {
          return item
        } else {
          const str_item = item.substr(0,2)
          if(str !== str_item) {
            return item
          }
        }
      })
    } else {
      selectedCode = selectedCode.filter((item:any) => {
        if(item.indexOf('0000') === -1) {
          return item
        } else {
          const str_item = item.substr(0,2)
          if(str !== str_item) {
            return item
          }
        }
      })
    }
    let selected_N:any[] = []
    selected.forEach((item1:any) => {
      selectedCode.forEach((item2:string) => {
        if(item1.code === item2) {
          selected_N.push(item1)
        }
      })
    })
    return selected_N
  }
  // 添加选中项
  handleItemClick = (item: subItem) => {
    const { edit, max, type } = this.props
    const existed = this.state.currentItems.filter(x => x.code === item.code).length > 0
    let result = uniqBy(xorBy(this.state.currentItems, [item], 'code'), 'code')
    if(type === 'City') {
      result = this.replaceArr(result, item.code)
    }
    if (edit) {
      if (result.length > max && max > 1) {
        Taro.showToast({
          title: `最多选择${max}项`,
          icon: 'none',
          mask: true,
        })
        return
      }
    }
    let menuCode: string[] = []
    this.props.options.forEach(x => {
      const res = x.sublist.filter(x => x.code === item.code)
      if (res.length > 0) {
        if (existed) {
          menuCode.splice(menuCode.indexOf(x.code), 1)
        } else {
          menuCode.push(x.code)
        }
      }
    })
    let currentMenus: string[] = []
    this.props.options.forEach(x => {
      if (x.sublist.filter(y => y.code === item.code)[0]) {
        this.props.options
          .filter(z => z.code === x.code)
          .forEach(zz => {
            const count = differenceBy(zz.sublist, this.state.currentItems, 'code').length
            if (zz.sublist.length - count === 1) {
              currentMenus.push(x.code)
            }
          })
      }
    })
    if (edit) {
      if (existed) {
        this.setState({
          highLightMenus: xor(this.state.highLightMenus, currentMenus),
        })
      } else {
        this.setState({
          highLightMenus: uniqBy([...this.state.highLightMenus, ...menuCode]),
        })
      }
    } else {
      if (existed) {
        this.setState({
          highLightMenus: [],
        })
      } else {
        this.setState({
          highLightMenus: menuCode,
        })
      }
    }
    this.props.onItemClick && this.props.onItemClick(item)
    if (this.props.edit) {
      this.handleChange(result)
      this.setState({
        currentItems: result,
        currentCount: result.length,
      })
    } else {
      if (this.props.radio) {
        this.setState({
          highLightMenus: [],
        })
        if (result.length > 1) {
          result.shift()
        }
      }
      this.setState({
        currentItems: result,
        currentCount: 1,
      })
    }
  }

  // 移除选中项
  handleItemRemove = (item: subItem) => {
    const { highLightMenus, currentItems } = this.state
    const result = currentItems.filter(x => x.code !== item.code)
    let currentMenu: string[] = []
    this.props.options.forEach(x => {
      if (x.sublist.filter(y => y.code === item.code)[0]) {
        this.props.options
          .filter(z => z.code === x.code)
          .forEach(zz => {
            const count = differenceBy(zz.sublist, currentItems, 'code').length
            if (zz.sublist.length - count === 1) {
              currentMenu.push(x.code)
            }
          })
      }
    })
    if (this.props.edit) {
      this.handleChange(result)
      this.setState({
        currentItems: result,
        currentCount: result.length,
        highLightMenus: xor(highLightMenus, currentMenu),
      })
    }
  }

  handleSave = () => {
    const { currentItems } = this.state
    this.props.onSave && this.props.onSave(currentItems)
  }

  handleChange = (result) => {
    this.props.onChange && this.props.onChange(result)
  }

  render() {
    const {
      currentItems,
      currentMenu,
      currentSubList,
      highLightMenus,
      currentCount,
      height,
      hasRegion,
    } = this.state
    const { edit, type, options, location, max } = this.props
    const isiPhoneXBottom  = Taro.getStorageSync('isiPhoneX') === 'true' ? '30Px;' : '15Px'

    // const isiPhoneX = Taro.getStorageSync('isiPhoneX') === 'true' ? true : false

    const isCity = type === 'City'
    const isNormal = type === 'Normal'
    const isGrid = type === 'Grid'
    const isList = type === 'List'
    return (
      <View className='page'>
        <Border1PxLine hasPB={false} />
        {/** 编辑 顶部 通用 */}
        {edit && (isCity || isNormal || isList) && (
          <View
            ref={this.refEdit}
            style={{
              position: 'relative',
            }}
          >
            {currentItems.length > 0 ? (
              <View
                className={classNames('edit', (currentItems as []).length === 0 && 'edit__noData')}
              >
                <View className='edit__place'>
                  {currentItems.map(item => (
                    <Block key={item.code}>
                      <View
                        className={classNames(
                          (isCity || isList) && 'edit__place_value',
                          isNormal && 'edit__place_normal'
                        )}
                      >
                        <View
                          className={classNames(
                            (isCity || isList) && 'edit__place_value_text',
                            isNormal && 'edit__place_normal_text'
                          )}
                          onClick={this.handleItemRemove.bind(this, item)}
                        >
                          {item.value}
                          <Image
                            className={classNames(
                              (isCity || isList) && 'edit__place_value_close',
                              isNormal && 'edit__place_normal_close'
                            )}
                            src='https://f3-v.veimg.cn/app/wx/ve/category-close@2x.png'
                            onClick={this.handleItemRemove.bind(this, item)}
                          />
                        </View>
                      </View>
                    </Block>
                  ))}
                </View>
              </View>
            ) : (
              <View className='edit__place-placehold'>最多可选择{max}个</View>
            )}
            <View className='edit__count'>
              <Text className='edit__count--highlight'>{currentCount}</Text>/{max}
            </View>
            {/* <View className='edit__base' /> */}
            <View className='edit__divider' />
          </View>
        )}
        <View className='cate'>
          {/** 编辑 菜单 List */}
          {edit && isList && (
            <ScrollView scrollY style={{ height }}>
              <EditMenuList
                currentItems={currentItems}
                list={options}
                onClick={this.handleItemClick}
              />
              <View className='cate-baseHeight' />
            </ScrollView>
          )}
          {/** 菜单 isCity || isNormal */}
          {(isCity || isNormal) && (
            <ScrollView
              scrollY
              className={classNames(isCity && 'cate-menu-city', isNormal && 'cate-menu')}
              style={{ height }}
            >
              <Menu
                edit={edit}
                type={type}
                highLightMenus={highLightMenus}
                current={currentMenu}
                list={options}
                onClick={this.handleMenuClick}
              />
              <View className='cate-baseHeight' />
            </ScrollView>
          )}
          {/** 非编辑 菜单 List */}
          {!edit && isList && (
            <ScrollView scrollY style={{ height }}>
              <EditMenuList
                currentItems={currentItems}
                list={options}
                onClick={this.handleItemClick}
              />
              <View className='cate-baseHeight' />
            </ScrollView>
          )}
          {!isList && (
            <ScrollView
              scrollY
              className={classNames(
                isCity && 'cate-content__city',
                isNormal && 'cate-content__normal',
                isGrid && 'cate-content__grid'
              )}
              style={{ height }}
            >
              <Content
                hasRegion={hasRegion}
                edit={edit}
                type={type}
                current={currentItems}
                location={location}
                list={isGrid ? options : currentSubList}
                onClick={this.handleItemClick}
              />
              <View className='cate-baseHeight' />
            </ScrollView>
          )}
        </View>
        {edit && max > 1 && (
          <View
            className={classNames('btn_wrap')}
            onClick={this.handleSave}
            style={{paddingBottom: isiPhoneXBottom}}
          >
            <View className='btn_wrap_save'>保存</View>
          </View>
        )}
      </View>
    )
  }
}
